[HVM] Save/restore: PV-on-HVM driver save/restore support
authorTim Deegan <Tim.Deegan@xensource.com>
Thu, 29 Mar 2007 16:27:52 +0000 (16:27 +0000)
committerTim Deegan <Tim.Deegan@xensource.com>
Thu, 29 Mar 2007 16:27:52 +0000 (16:27 +0000)
Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
tools/python/xen/lowlevel/xc/xc.c
tools/python/xen/xend/XendConstants.py
tools/python/xen/xend/XendDomainInfo.py
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
xen/arch/x86/hvm/hvm.c

index 0dcd2fa252925d4c4f43882d8b7f45be3e4915df..aa6215c93ed86d2cf8cfbb706e97fa99363f14eb 100644 (file)
@@ -33,7 +33,24 @@ static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
 #ifdef CONFIG_XEN
 int __xen_suspend(int fast_suspend);
 #else
-#define __xen_suspend(fast_suspend) 0
+extern void xenbus_suspend(void);
+extern void xenbus_resume(void);
+extern void platform_pci_suspend(void);
+extern void platform_pci_resume(void);
+int __xen_suspend(int fast_suspend)
+{
+       xenbus_suspend();
+       platform_pci_suspend();
+
+       /* pvdrv sleep in this hyper-call when save */
+       HYPERVISOR_shutdown(SHUTDOWN_suspend);
+
+       platform_pci_resume();
+       xenbus_resume();
+       printk("PV stuff on HVM resume successfully!\n");
+
+       return 0;
+}
 #endif
 
 static int shutdown_process(void *__unused)
index 975b7d3a3808d95829183b1fb37a00f2ed562fda..c40a900cb34ddbc62478d8032d695793934d0ba1 100644 (file)
@@ -467,6 +467,26 @@ static PyObject *pyxc_linux_build(XcObject *self,
     return pyxc_error_to_exception();
 }
 
+static PyObject *pyxc_get_hvm_param(XcObject *self,
+                                    PyObject *args,
+                                    PyObject *kwds)
+{
+    uint32_t dom;
+    int param;
+    unsigned long value;
+
+    static char *kwd_list[] = { "domid", "param", NULL }; 
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
+                                      &dom, &param) )
+        return NULL;
+
+    if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
+        return pyxc_error_to_exception();
+
+    return Py_BuildValue("i", value);
+
+}
+
 static PyObject *pyxc_hvm_build(XcObject *self,
                                 PyObject *args,
                                 PyObject *kwds)
@@ -1225,6 +1245,14 @@ static PyMethodDef pyxc_methods[] = {
       " vcpus   [int, 1]:   Number of Virtual CPUS in domain.\n\n"
       "Returns: [int] 0 on success; -1 on error.\n" },
 
+    { "hvm_get_param", 
+      (PyCFunction)pyxc_get_hvm_param, 
+      METH_VARARGS | METH_KEYWORDS, "\n"
+      "get a parameter of HVM guest OS.\n"
+      " dom     [int]:      Identifier of domain to build into.\n"
+      " param   [int]:      No. of HVM param.\n"
+      "Returns: [int] value of the param.\n" },
+
     { "sched_id_get",
       (PyCFunction)pyxc_sched_id_get,
       METH_NOARGS, "\n"
index e6bc7873403e8468748dc59bafae5e4b0c3b6b1a..d7469ce5fe8828f841223ee30f911e257443b5aa 100644 (file)
@@ -37,6 +37,13 @@ DOMAIN_SHUTDOWN_REASONS = {
 REVERSE_DOMAIN_SHUTDOWN_REASONS = \
     dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()])
 
+HVM_PARAM_CALLBACK_IRQ = 0
+HVM_PARAM_STORE_PFN    = 1
+HVM_PARAM_STORE_EVTCHN = 2
+HVM_PARAM_PAE_ENABLED  = 4
+HVM_PARAM_IOREQ_PFN    = 5
+HVM_PARAM_BUFIOREQ_PFN = 6
+
 restart_modes = [
     "restart",
     "destroy",
index 4b155c3dacb402ef852e5b578f331ac5b16c2ee5..3fdba4d8f2fb4ec8693da4342aa041ebb801ca84 100644 (file)
@@ -448,11 +448,12 @@ class XendDomainInfo:
         self._removeVm('xend/previous_restart_time')
         self.storeDom("control/shutdown", reason)
 
-        ## shutdown hypercall for hvm domain desides xenstore write
-        if self.info.is_hvm():
-            for code in DOMAIN_SHUTDOWN_REASONS.keys():
-                if DOMAIN_SHUTDOWN_REASONS[code] == reason:
-                    break
+        ## HVM domain shutdown itself if has PV driver,
+        ## otherwise remote shutdown it
+        hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ)
+        if self.info.is_hvm() and not hvm_pvdrv:
+            code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
+            log.info("HVM save:remote shutdown dom %d!", self.domid)
             xc.domain_shutdown(self.domid, code)
 
 
index bb7120b028c08a5adc7fcd9f2529a968c6cdb47d..c9f6d73109d52e7f375be79c2330de44a99d3aa6 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/pgtable.h>
 #include <xen/interface/memory.h>
 #include <xen/features.h>
+#include <xen/gnttab.h>
 #ifdef __ia64__
 #include <asm/xen/xencomm.h>
 #endif
@@ -61,9 +62,11 @@ MODULE_LICENSE("GPL");
 unsigned long *phys_to_machine_mapping;
 EXPORT_SYMBOL(phys_to_machine_mapping);
 
+static unsigned long shared_info_frame;
+static uint64_t callback_via;
+
 static int __devinit init_xen_info(void)
 {
-       unsigned long shared_info_frame;
        struct xen_add_to_physmap xatp;
        extern void *shared_info_area;
 
@@ -219,7 +222,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
        int i, ret;
        long ioaddr, iolen;
        long mmio_addr, mmio_len;
-       uint64_t callback_via;
 
        i = pci_enable_device(pdev);
        if (i)
@@ -303,6 +305,35 @@ static struct pci_driver platform_driver = {
 
 static int pci_device_registered;
 
+void platform_pci_suspend(void)
+{
+       gnttab_suspend();
+}
+EXPORT_SYMBOL_GPL(platform_pci_suspend);
+
+void platform_pci_resume(void)
+{
+       struct xen_add_to_physmap xatp;
+       phys_to_machine_mapping = NULL;
+
+       /* do 2 things for PV driver restore on HVM
+        * 1: rebuild share info
+        * 2: set callback irq again
+        */
+       xatp.domid = DOMID_SELF;
+       xatp.idx = 0;
+       xatp.space = XENMAPSPACE_shared_info;
+       xatp.gpfn = shared_info_frame;
+       if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+               BUG();
+
+       if (( set_callback_via(callback_via)))
+               printk("platform_pci_resume failure!\n");
+
+       gnttab_resume();
+}
+EXPORT_SYMBOL_GPL(platform_pci_resume);
+
 static int __init platform_pci_module_init(void)
 {
        int rc;
index 2c783bfe7a53e07454265ae61ec2c6b712de8367..8bdd956186f927a2b6661a85d29288894055db98 100644 (file)
@@ -556,6 +556,7 @@ static hvm_hypercall_t *hvm_hypercall_table[NR_hypercalls] = {
     HYPERCALL(multicall),
     HYPERCALL(xen_version),
     HYPERCALL(event_channel_op),
+    HYPERCALL(sched_op),
     HYPERCALL(hvm_op)
 };